package com.wedistudio.slideshare.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.simpleframework.xml.Serializer;

import com.wedistudio.android.framework.fetcher.URLParams;
import com.wedistudio.android.framework.pool.PoolFactory;
import com.wedistudio.android.framework.service.Service;
import com.wedistudio.android.framework.service.ServiceException;
import com.wedistudio.android.framework.service.ServiceRequestConverter;
import com.wedistudio.android.framework.service.ServiceResponseConverter;
import com.wedistudio.slideshare.SlideshareUtils;
import com.wedistudio.slideshare.xml.Slideshow;
import com.wedistudio.slideshare.xml.Slideshows;
import com.wedistudio.slidesprovider.Language;
import com.wedistudio.slidesprovider.SearchCriteria;
import com.wedistudio.slidesprovider.Slide;
import com.wedistudio.slidesprovider.Slides;
import com.wedistudio.slidesprovider.SortBy;

public class GetSlidesFromCriteria extends Service<SearchCriteria, Slides> {

	static public GetSlidesFromCriteria create() {
		return new GetSlidesFromCriteria();
	}

	private static String SEARCH_SLIDESHOW = "search_slideshows";

	private String orderby(SortBy order) {
		switch (order) {
		case RELEVENCE:
			return "relevance";
		case LAST_PUBLISHED:
			return "latest";
		case POPULARITY:
			return "mostviewed";
		}
		return null;
	}

	private String lang(Language language) {
		switch (language) {
		case ANY:
			return "**";
		case ARABIC:
			return "!!";
		case CHINESE:
			return "zh*";
		case DUTCH:
			return "nl";
		case ENGLISH:
			return "en";
		case FRENCH:
			return "fr";
		case GERMAN:
			return "de";
		case ITALIAN:
			return "it";
		case JAPANESE:
			return "ja";
		case KOREAN:
			return "ko";
		case OTHER:
			return "!!";
		case PORTUGUESE:
			return "pt";
		case ROMANIAN:
			return "ro";
		case SPANISH:
			return "**";

		}

		return "**";
	}

	private GetSlidesFromCriteria() {
		setRequestConverter(new ServiceRequestConverter<SearchCriteria>() {

			@Override
			public List<URLParams> convert(SearchCriteria request)
					throws ServiceException {

				List<URLParams> result = new ArrayList<URLParams>();
				URLParams params = SlideshareUtils
						.buildURLParams(SEARCH_SLIDESHOW);
				params.addParam("q", request.getKeyword());
				params.addParam("page",
						"" + (1 + request.getOffset() / request.getLimit()));
				params.addParam("items_per_page", "" + request.getLimit());
				params.addParam("sort", orderby(request.getSort()));
				params.addParam("lang", lang(request.getLanguage()));
				result.add(params);
				return result;
			}
		});

		setResponseConverter(new ServiceResponseConverter<Slides>() {

			@Override
			public Slides convert(Map<URLParams, String> raw)
					throws ServiceException {
				Serializer serializer = null;
				try {
					String xml = null;
					for (Map.Entry<URLParams, String> entry : raw.entrySet()) {
						xml = entry.getValue();
						SlideshareUtils.checkResponse(xml);
					}

					serializer = PoolFactory.get(Serializer.class);

					Slideshows slideshows = serializer.read(Slideshows.class,
							xml);

					Slides result = new Slides(slideshows.Meta.Query,
							slideshows.Meta.TotalResults,
							slideshows.Meta.ResultOffset);

					for (final Slideshow slideshow : slideshows.slideshows) {
						Slide slide = slideshow.getSlide();
						result.add(slide);
					}
					return result;
				} catch (ServiceException e) {
					throw e;
				} catch (Throwable e) {
					throw new ServiceException(e);
				} finally {
					PoolFactory.release(serializer, Serializer.class);
				}
			}
		});
	}
}
